
import pickle 
import numpy as np
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

import time
import numpy as np
import pickle
global totaltime
global searchv
global searchposition
global callerposition
global callerstatus
global callernumber
global callerwait
global callerhelptime
global searchstatus
global totaltime
global saverposition
global savertarget
global saverposition
global saverroute
global saverstatus
global callerneaddealtme
global ttip
searchv=10
saverv=2
def datainit():
    global callernumber
    global searchposition
    global searchstatus
    global callerposition
    global callerstatus
    global callerwait
    global totaltime
    global saverposition
    global savertarget
    global saverposition
    global savertarget
    global saverstatus
    global callerneaddealtme
    global callertotaltime
    global saverroute
    global callerreachtime
    global callerhelptime
    global callerfinaltime
    global ttip
    ttip=0
    saverroute=[[],[],[],[]]
    saverposition=np.array([[0,0],
                            [0,0],
                            [0,0],
                            [0,0]
                            ],dtype=np.double)
    savertarget=np.array([[0,0],
                        [0,0],
                        [0,0],
                        [0,0],
                        ],dtype=np.double)
    saverstatus=np.array([0,0,0,0])
    totaltime=0
    searchposition=[]
    searchstatus=np.array([0,0,0,0,0,0,0,0,0])
    callerposition=[]
    x=20
    y=0
    
    for m in range(3):
        x=x+m*500
        for n in range(3):
            y=y+n*500
            searchposition.append([x,y])
            y=0
        x=20
    searchposition=np.asarray(searchposition)
    
    node=[[0,0],[0,500],[0,1000],
          [500,0],[500,500],[500,1000],
          [1000,0],[1000,500],[1000,1000]
          ]
    
    for m in range(20):
        callerposition.append([np.random.rand()*1500,np.random.rand()*1500])
    callerposition=np.asarray(callerposition)
    
    callernumber=np.size(callerposition,0)
    

    callerstatus=np.zeros([callernumber,1])
    callerwait=np.zeros([callernumber,1])
    callerhelptime=np.zeros([callernumber,1]) 
    callerneaddealtme=np.array([np.random.randint(600,650) for n in range(callernumber)])
    callertotaltime=np.zeros([callernumber,1])
    callhelptime=np.zeros([callernumber,1])
    callerreachtime=np.zeros([callernumber,1])
    callerfinaltime=np.zeros([callernumber,1])

    

    #print np.size(callerstatus,0)
    #print np.size(callerposition,0)
    #print '=============================='
    
    

    
def searchmove():
    global searchposition
    global searchstatus
    global searchv
    global totaltime
    #if searchposition[1][0]%20==0:
            #print searchstatus
    for n in range(9):
        if searchstatus[n]==0:
            searchposition[n]=[searchposition[n][0],searchposition[n][1]+searchv]
        if searchstatus[n]==1:
            searchposition[n]=[searchposition[n][0]+searchv,searchposition[n][1]]
        if searchstatus[n]==2:
            searchposition[n]=[searchposition[n][0],searchposition[n][1]-searchv]
        if searchstatus[n]==3:
            searchposition[n]=[searchposition[n][0]+searchv,searchposition[n][1]]


        if (  searchposition[n][0]   % 20 ==0) and ( searchposition[n][1] % 500 == 0 ):
            
            
                
            if searchstatus[n]==0:
                searchstatus[n]=1
                #print '1'
                continue
            if searchstatus[n]==1:
                searchstatus[n]=2
                #print '2'
                continue
                
            if searchstatus[n]==2:
                #print '3'
                searchstatus[n]=3
                continue
            if searchstatus[n]==3:
                searchstatus[n]=0
                continue
                #print '0'
    #if searchposition[1][0]%20==0:
    #            print searchstatus
def time():
    global totaltime
    totaltime=totaltime+1
def justify():
    global searchposition
    global callerposition
    global callerwait
    global totaltime
    global callerstatus
    global callerneaddealtme
    for m in range(np.size(searchposition,0)):
        for n in range(np.size(callerposition,0)):
            if (np.sqrt((searchposition[m][0]-callerposition[n][0])*(searchposition[m][0]-callerposition[n][0])+(searchposition[m][1]-callerposition[n][1])*(searchposition[m][1]-callerposition[n][1])))<=25:
                callerwait[n]=totaltime
                if callerstatus[n]==0:
                    callerstatus[n]=1

def savermove():
    global callerneaddealtme
    global saverposition
    global callerstatus
    global totaltime
    global callerposition
    global callerreachtime
    global callerfinaltime
    global callerhelptime
    global saverroute
    for m in range(np.size(saverposition,0)):
        if saverstatus[m]==0:
            for n in range(np.size(callerstatus,0)):
                if (callerstatus[n]==1 ):
                    savertarget[m]=callerposition[n]
                    saverroute[m].append(callerposition[n])
                    #print callerposition[n]
                    #print savertarget[m]
                    saverstatus[m]=1
                    callerstatus[n]=2
                    break
    
        if saverstatus[m]==1:
            #print 'yes move'
            if np.sqrt((saverposition[m][0]-savertarget[m][0])**2+(saverposition[m][1]-savertarget[m][1])**2)<2:
                saverstatus[m]=2
                for n in range(np.size(callerposition,0)):
                    if [x for x in callerposition[n]]==[y for y in savertarget[m]]:
                        callerreachtime[n]=totaltime
            else:
                x=savertarget[m][0]-saverposition[m][0]
                #print x
                y=savertarget[m][1]-saverposition[m][1]
                #print y
                r=np.sqrt((saverposition[m][0]-savertarget[m][0])**2+(saverposition[m][1]-savertarget[m][1])**2)
                #print r

                cos=(x*1.0)/(r*1.0)
                sin=(y*1.0)/(r*1.0)
                saverposition[m][0]=saverposition[m][0]*1.0+saverv*cos*1.0
                #print saverposition[m][0]
                saverposition[m][1]=saverposition[m][1]*1.0+saverv*sin*1.0
                #print saverposition[m][1]

        if saverstatus[m]==2:
            for n in range(np.size(callerposition,0)):
                if [x for x in callerposition[n]]==[y for y in savertarget[m]]:
                    if callerneaddealtme[n]!=0:
                        callerneaddealtme[n]=callerneaddealtme[n]-1
                        callerhelptime[n]=callerhelptime[n]+1
                    else:
                        saverstatus[m]=0
                        callerfinaltime[n]=totaltime
                        callerstatus[n]=3
                    break

                
        

def justifysaver():
    global callerhelptime
    global callerneaddealtme
    global callertotaltime
    global saverroute
    global savertarget
    for m in range(np.size(saverposition,0)):
        tip=0
        temp=0
        for n in saverroute[m]:
            if n==savertarget[m]:
                tip=1
                temp=savertarget
                break
        if tip==1:
            saverroute[m].append(temp)






def init():
    glClearColor(0.0, 0.0, 0.0, 1.0)
    gluOrtho2D(0, 1500, 0, 1500)
        
def doit():
    global callerposition
    global searchposition
    global callerstatus
    global callernumber
    global saverposition
    global totaltime
    global saverroute
    global ttip
    time()
    searchmove()
    justify()
    
    if ttip==0:
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glPointSize(4)
        for m in range(callernumber):
            glBegin(GL_POINTS)
            if callerstatus[m]==0:
                glColor3f(255.0, 0.0, 0.0)
            if callerstatus[m]==1:
                glColor3f(255.0, 0.0, 255.0)
            if callerstatus[m]==2:
                glColor3f(255.0, 0.0, 255.0)           
            if callerstatus[m]==3:
                glColor3f(0.0, 0.0, .0)
            glVertex2f(callerposition[m][0], callerposition[m][1])
            glEnd()

        for m in range(np.size(searchposition,0)):
            glBegin(GL_POINTS)
            glColor3f(0.0, 1.0, 0.0)
            glVertex2f(searchposition[m][0], searchposition[m][1])
            glEnd()  
        savermove()
        for m in range(np.size(saverposition,0)):
            glBegin(GL_POINTS)
            glColor3f(255,64,64)
        
            glVertex2f(saverposition[m][0],saverposition[m][1])
            glEnd()
        tip=0
        for n in callerstatus:
            if n!=3:
                tip=1
                break
        if tip==0:
            entry={}
            entry['finaltime']=callerfinaltime
            entry['callerreachtime']=callerreachtime
            entry['callerwait']=callerwait
            entry['router']=saverroute
            with open('entry.pickle','wb') as f:
                pickle.dump(entry,f)
            ttip=1
            print saverroute
            print 'end'
    else:
        print 'print 2'

        for m in range(np.size(savertarget,0)):
            tttip=0
            for n in range(1,np.size(saverroute[m],0)):
                glBegin(GL_LINES)
                if m==0:
                    glColor3f(1,0,0 )
                if m==1:
                    glColor3f(0,1,0)
                if m==2:
                    glColor3f(0,0,1)
                if m==3:
                    glColor3f(1,0,1)
                if  tttip==0:
                    glVertex2f(0,0)
                    glVertex2f(saverroute[m][n-1][0], saverroute[m][n-1][1])
                    glVertex2f(saverroute[m][n-1][0], saverroute[m][n-1][1])
                    glVertex2f(saverroute[m][n][0],saverroute[m][n][1])
                    tttip=tttip+1
                else:
                                   
                    glVertex2f(saverroute[m][n-1][0], saverroute[m][n-1][1])
                    glVertex2f(saverroute[m][n][0],saverroute[m][n][1])
                glEnd()
        print "can final"         
    glFlush()

datainit()
glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(600, 600)
glutCreateWindow("First")
glutDisplayFunc(doit)
glutIdleFunc(doit)
init()
glutMainLoop()




